﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using MongoDB.Driver;

namespace NetCoreQrCoreDemo.Models
{
    public class MongoHelper
    {
        private readonly IMongoDatabase _database = null;
        public MongoHelper(string connectionString, string databaseName)
        {
            var client = new MongoClient(connectionString);
            if (client != null)
            {
                _database = client.GetDatabase(databaseName);
            }
        }

        #region SELECT
        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<T> GetList<T>(Expression<Func<T, bool>> conditions = null)
        {
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            if (conditions != null)
            {
                return collection.Find(conditions).ToList();
            }
            return collection.Find(_ => true).ToList();
        }
        #endregion

        #region SELECT
        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T FindNoe<T>(Expression<Func<T, bool>> conditions = null)
        {
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            if (conditions != null)
            {
                return  collection.Find<T>(conditions).FirstOrDefault();
            }
            return collection.Find(_ => true).FirstOrDefault();
        }
        #endregion

        #region INSERT
        /// <summary>
        /// 插入多条数据，数据用list表示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<T> InsertMany<T>(List<T> list)
        {
            if (!list.Any()) return list;
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            collection.InsertMany(list);
            return list;
        }

        public T Insert<T>(T model)
        {
            if (model == null) return model;
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            collection.InsertOne(model);
            return model;
        }

        public async Task<T> InsertAsync<T>(T model)
        {
            if (model == null) return model;
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
           await collection.InsertOneAsync(model);
            return model;
        }
        #endregion

        #region Update
        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T">传入对象</typeparam>
        /// <param name="conditions">条件</param>
        /// <param name="model">修改的对象</param>
        /// <returns></returns>
        public T Update<T>(FilterDefinition<T> conditions, T model)
        {
            if (model == null) return model;
            //获取特性内容
           Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            //collection.ReplaceOne(conditions, model);
            collection.FindOneAndReplace(conditions, model);
            return model;
        }
         public void UpdateMany<T>(FilterDefinition<T> conditions,UpdateDefinition<T>  model)
        {
            if (model == null) return ;
            //获取特性内容
           Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName); 
            collection.UpdateMany(conditions, model); 
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T">传入对象</typeparam>
        /// <param name="conditions">条件</param>
        /// <param name="model">修改的对象</param>
        /// <returns></returns>
        public async Task<T> UpdateAsync<T>(FilterDefinition<T> conditions, T model)
        {
            if (model == null) return model;
            //获取特性内容
            Attribute.MongoAttribute attribute = (Attribute.MongoAttribute)typeof(T).GetCustomAttribute(typeof(Attribute.MongoAttribute), true);
            var collection = _database.GetCollection<T>(attribute.CollectionName);
            await collection.FindOneAndReplaceAsync<T>(conditions, model);
            //await collection.ReplaceOneAsync(conditions, model); 
            return model;
        }
        #endregion
    }
}